from rest_framework.parsers import JSONParser
from django.utils.six import BytesIO
from django.shortcuts import render
from OMAI.models import Features
from OMAI.serializers import FeaturesSerializer
from rest_framework import generics
from rest_framework import permissions
from OMAI.permissions import IsOwnerOrReadOnly
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.reverse import reverse
from OMAI.lnnModel import LnnModel
from rest_framework import status
import numpy as np
import sqlite3
import pickle
import json
from OMAI.TrainingModel import TrainingModel


# Create your views here.
from rest_framework import mixins
from rest_framework import generics

class FeaturesList(mixins.ListModelMixin,
                   mixins.CreateModelMixin,
                   generics.GenericAPIView):

    queryset = Features.objects.all()
    serializer_class = FeaturesSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,
                          IsOwnerOrReadOnly,)

    def listToStringWithoutBrackets(self, l):
        return str(l).replace('[','').replace(']','')

    def get(self, request, *args, **kwargs):

        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        
        # Create LNN Model instance
        ai_engine = LnnModel()

        #Load the parameters trained previously
        pkl_file = open('parameters.pkl', 'rb')

        parameters = pickle.load(pkl_file)

        #Specify the NN structure, Note: Use the same structure when training the model
        layer_dims = [8,4,4,6]
      
        #Retrive the input features from the post data
        input_feature = np.zeros((layer_dims[0],1))
        for i in range (0,layer_dims[0]):
            input_feature[i] =  float(request.data['x'+str(i+1)])

        #print('input_feature X is:' + str(input_feature))
         
        # Make the prediction
        A,cache = ai_engine.L_model_forward(input_feature, parameters)
        
        results = self.listToStringWithoutBrackets(A.tolist())

        #return self.create(request, *args, **kwargs)

        return Response(A.tolist(), status=status.HTTP_201_CREATED)

class KickoffTraining(mixins.ListModelMixin,
                      mixins.CreateModelMixin,
                      generics.GenericAPIView):

    #conn = sqlite3.connect('db.sqlite3', detect_types=sqlite3.PARSE_DECLTYPES)
    #c = conn.cursor()

    def get(self, request, *args, **kwargs):         
        ai_engine = LnnModel()
        training = TrainingModel(ai_engine)
        parameters = training.L_layer_model(0.0075, 3000, True)

        output = open('parameters.pkl', 'wb')

        # Pickle dictionary using protocol 0.
        pickle.dump(parameters, output)

        output.close()

        return Response(parameters, status=status.HTTP_201_CREATED)


@api_view(['GET','POST'])
def api_root(request, format=None):
    return Response({
        'predict': reverse('predict', request=request, format=format),
        'training': reverse('training', request=request, format=format),
    })

